"""Implementation of the GeminiGenie class."""
import importlib.util as importutil
import json
import os
from typing import TYPE_CHECKING, Any, Dict, Optional

from .base import BaseGenie

if TYPE_CHECKING:
    from pydantic import BaseModel

###################### 修改替换chonkie.genie ######################
from abc import ABC, abstractmethod


class BaseGenie(ABC):
    """Genie抽象基类。"""
    
    def __init__(self):
        """Initialize the BaseGenie class."""
        self._import_dependencies()
    
    @abstractmethod
    def generate(self, prompt: str) -> str:
        """Generate a response based on the given prompt."""
        pass
    
    @abstractmethod
    def generate_json(self, prompt: str, schema: "BaseModel") -> Dict[str, Any]:
        """Generate a JSON response based on the given prompt and schema."""
        pass
    
    def _import_dependencies(self) -> None:
        """Import all the required dependencies."""
        pass
    
    def _is_available(self) -> bool:
        """Check if the required dependencies are available."""
        try:
            import requests
            import json
            from pydantic import BaseModel
            return True
        except ImportError:
            return False

class QwenGenie(BaseGenie):
    """千问百练云的Genie实现。"""

    def __init__(self,
                model: str = "qwen-plus-latest",
                api_key: Optional[str] = None,
                base_url: str = "https://dashscope.aliyuncs.com/compatible-mode/v1"):
        """Initialize the QwenGenie class.

        Args:
            model (str): The model to use.
            api_key (Optional[str]): The API key to use.
            base_url (str): 千问百练云API的基础URL

        """
        super().__init__()

        # Lazily import the dependencies
        self._import_dependencies()

        # Initialize the API key and base URL
        self.api_key = api_key = api_key 
        if not self.api_key:
            raise ValueError("QwenGenie需要API密钥。请传递`api_key`参数。")

        # Initialize the model and base URL
        self.model = model
        self.base_url = base_url
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}"
        }

    def generate(self, prompt: str) -> str:
        """根据给定的提示生成响应。"""
        import json
        url = f"{self.base_url}/chat/completions"
        payload = {
            "model": self.model,
            "messages": [
                {"role": "user", "content": prompt}
            ],
            "temperature": 0.7
        }
        
        try:
            response = requests.post(url, headers=self.headers, data=json.dumps(payload))
            response.raise_for_status()  # Raise exception for HTTP errors
            result = response.json()
            return result["choices"][0]["message"]["content"]
        except Exception as e:
            raise ValueError(f"Failed to generate response: {e}")
    
    def generate_json(self, prompt: str, schema: "BaseModel") -> Dict[str, Any]:
        """根据给定的提示和模式生成JSON响应。"""
        # 修改提示词，要求返回JSON格式
        json_prompt = f"{prompt}\n\n请以JSON格式返回结果，确保是有效的JSON，不要包含JSON之外的任何内容。"
        
        try:
            response_text = self.generate(json_prompt)
            # 尝试解析JSON响应
            return dict(json.loads(response_text))
        except Exception as e:
            raise ValueError(f"Failed to parse JSON response: {e}")

    def _is_available(self) -> bool:
        """检查所有依赖项是否已存在于环境中。"""
        if (importutil.find_spec("pydantic") is not None \
            and importutil.find_spec("requests") is not None \
            and importutil.find_spec("json") is not None):
            return True
        return False

    def _import_dependencies(self) -> None:
        """导入所有必需的依赖项。"""
        if self._is_available():
            global BaseModel, requests, json
            import requests
            import json
            from pydantic import BaseModel
        else:
            raise ImportError("One or more of the required modules are not available: [pydantic, requests, json]")
    
    def __repr__(self) -> str:
        """返回QwenGenie实例的字符串表示形式。"""
        return f"QwenGenie(model={self.model})"
###################### 修改替换chonkie.genie ######################